package com.enqualcomm.kids.mvp.silent;

import android.view.View;
import android.widget.ImageView;

import com.android.volley.NetworkResponse;
import com.android.volley.socket.SocketClient;
import com.android.volley.socket.SocketNetwork;
import com.enqualcomm.kids.base.BaseActivity;
import com.enqualcomm.kids.bean.SilenceTime;
import com.enqualcomm.kids.component.MyApplication;
import com.enqualcomm.kids.config.userdefault.AppDefault;
import com.enqualcomm.kids.network.Parser;
import com.enqualcomm.kids.network.SocketRequest;
import com.enqualcomm.kids.network.socket.request.BasicParams;
import com.enqualcomm.kids.network.socket.request.QuerySilenceParams;
import com.enqualcomm.kids.network.socket.request.TerminalListParams;
import com.enqualcomm.kids.network.socket.response.BasicResult;
import com.enqualcomm.kids.network.socket.response.QuerySilenceResult;
import com.enqualcomm.kids.network.socket.response.TerminallistResult;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import common.utils.NetUtil;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by yinzhiqun on 2015/11/21.
 *
 */
public class SilentDelegateImpl implements SilentDelegate {

    BaseActivity context;
    ImageView imageView;
    SocketNetwork socketNetwork;
    ArrayList<String> onSilentModeTerminals;
    HashMap<String,List<SilenceTime>> silenceTimes;
    Subscription subscription;
    Timer timer;

    private String currentTerminanlid;
    private Subscription subscription2;

    // 1.onStart时取所有手表的静默时段信息
    // 2.对数据进行预处理
    // 3.起定时器
    // 4.onStop时销毁所有定时器
    // 5.维护所有手表的静默状态
    // 6.传入ImageView，直接在内部修改状态

    public SilentDelegateImpl(BaseActivity context) {
        this.context = context;
        socketNetwork = SocketClient.initSocketNetwork(context);
    }


    @Override
    public void setSilentToken(ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    public void onStart() {
        if (subscription!=null) {
            subscription.unsubscribe();
            subscription =null;
        }

        //如果有历史数据，先根据历史数据判断一次
//        if (silenceTimes!=null && currentTerminanlid!=null &&check(currentTerminanlid)){
//            imageView.setVisibility(View.VISIBLE);
//        }else{
//            imageView.setVisibility(View.INVISIBLE);
//        }

        //terminallist时，服务器会给静默时段个数,可以根据这个数量决定是否获取
        AppDefault appDefault = new AppDefault();
        final String userid = appDefault.getUserid();
        final String userkey = appDefault.getUserkey();

        onSilentModeTerminals  = new ArrayList<>();
        silenceTimes = new HashMap<>();

        subscription = Observable.create(new Observable.OnSubscribe<TerminallistResult>() {
            @Override
            public void call(Subscriber<? super TerminallistResult> subscriber) {
                TerminallistResult result = loadData(new TerminalListParams(userkey, userid), TerminallistResult.class);
                subscriber.onNext(result);
                subscriber.onCompleted();
            }
        }).filter(new Func1<TerminallistResult, Boolean>() {
            @Override
            public Boolean call(TerminallistResult terminallistResult) {
                return terminallistResult != null && terminallistResult.code == 0;
            }
        }).flatMap(new Func1<TerminallistResult, Observable<TerminallistResult.Terminal>>() {
            @Override
            public Observable<TerminallistResult.Terminal> call(TerminallistResult terminallistResult) {
                return Observable.from(terminallistResult.result);
            }
        }).filter(new Func1<TerminallistResult.Terminal, Boolean>() {
            @Override
            public Boolean call(TerminallistResult.Terminal terminal) {
                return terminal.icon.silence > 0;
            }
        }).map(new Func1<TerminallistResult.Terminal, QuerySilenceResult>() {
            @Override
            public QuerySilenceResult call(TerminallistResult.Terminal terminal) {
                QuerySilenceResult querySilenceResult = loadData(new QuerySilenceParams(userkey, terminal.terminalid), QuerySilenceResult.class);
                if (querySilenceResult!=null){
                    querySilenceResult.terminalid = terminal.terminalid;
                }
                return querySilenceResult;
            }
        }).filter(new Func1<QuerySilenceResult, Boolean>() {
            @Override
            public Boolean call(QuerySilenceResult querySilenceResult) {
                return querySilenceResult != null && querySilenceResult.code == 0;
            }
        }).map(new Func1<QuerySilenceResult, String>() {
            @Override
            public String call(QuerySilenceResult querySilenceResult) {
                //对数据进行预处理
                return processData(querySilenceResult);
            }
        }).filter(new Func1<String, Boolean>() {
            @Override
            public Boolean call(String s) {
                return check(s);
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {//状态都已经更新完毕
                changeTerminal(currentTerminanlid);
                startTimer();
            }

            @Override
            public void onError(Throwable e) {
                changeTerminal(currentTerminanlid);
                startTimer();
            }

            @Override
            public void onNext(String terminalid) {//调用到这里，都是在静默时间段内的手表
                onSilentModeTerminals.add(terminalid);
            }
        });
    }

    private void checkAllTerminal() {
        if (silenceTimes!=null){
            if (subscription2!=null) {
                subscription2.unsubscribe();
                subscription2 =null;
            }
            onSilentModeTerminals.clear();
            subscription2 = Observable.from(silenceTimes.keySet())
                    .filter(new Func1<String, Boolean>() {
                        @Override
                        public Boolean call(String s) {
                            return check(s);
                        }
                    }).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<String>() {
                        @Override
                        public void onCompleted() {
                            changeTerminal(currentTerminanlid);
                        }

                        @Override
                        public void onError(Throwable e) {
                            changeTerminal(currentTerminanlid);
                        }

                        @Override
                        public void onNext(String terminalid) {
                            onSilentModeTerminals.add(terminalid);
                        }
                    });
        }
    }


    /**
     * 启动定时器，定时检查所有手表的状态
     */
    private void startTimer() {
        if (timer!=null){
            timer.cancel();
        }
        timer = new Timer("check_silence");
        int second = Calendar.getInstance().get(Calendar.SECOND);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                checkAllTerminal();
            }
        }, (60-second)*1000, 60000);//尽量放在整点更新
    }

    private boolean check(String terminalid){
        List<SilenceTime> times = this.silenceTimes.get(terminalid);
        if (times!=null&&times.size()>0){

            int currentTime = getCurrentTime(Calendar.getInstance());
            for (SilenceTime time : times) {
                if (time.start<=currentTime && time.end >= currentTime){
                    return true;
                }
            }
        }
        return false;
    }

    private String processData(QuerySilenceResult querySilenceResult){
        Calendar calendar = Calendar.getInstance();
        int currentTime = getCurrentTime(calendar);
        int week = getCurrentWeek(calendar);

        ArrayList<SilenceTime> silenceTimes = new ArrayList<>();
        for (QuerySilenceResult.Data data : querySilenceResult.result) {
            if (data.isopen==1 && (data.week & week) == week){//排除关闭的和不包含当天的

                int endtime = parseTime(data.endtime);
                if (endtime >= currentTime){//排除掉已经过时的

                    int starttime = parseTime(data.begintime);
                    silenceTimes.add(new SilenceTime(starttime,endtime));
                }
            }
        }

        this.silenceTimes.put(querySilenceResult.terminalid, silenceTimes);
        return querySilenceResult.terminalid;
    }

    private int getCurrentTime(Calendar calendar){
        int hour = calendar.get(Calendar.HOUR_OF_DAY) * 100;
        int minute = calendar.get(Calendar.MINUTE);
        return hour+minute;
    }

    private int parseTime(String timeStr){
        timeStr = timeStr.replace(":","");
        return Integer.parseInt(timeStr);
    }

    private int getCurrentWeek(Calendar calendar){
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        return (int) Math.pow(2, (week - 1));
    }

    private <T> T loadData(BasicParams params,Class<T> clazz){
        if (NetUtil.checkNet(MyApplication.getInstance())){
            try {
                NetworkResponse networkResponse = socketNetwork.performRequest(new SocketRequest<BasicResult>(params, null));
                return Parser.parse(networkResponse, clazz);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void onStop() {
        if (subscription!=null) {
            subscription.unsubscribe();
            subscription =null;
        }
        if (subscription2!=null) {
            subscription2.unsubscribe();
            subscription2 =null;
        }
        if (timer!=null){
            timer.cancel();
            timer = null;
        }
    }

    @Override
    public void changeTerminal(String terminalid) {
        if (terminalid!=null){
            currentTerminanlid = terminalid;
            //查询该手表当前的状态
            if (onSilentModeTerminals!=null&&onSilentModeTerminals.contains(terminalid)){
                imageView.setVisibility(View.VISIBLE);
            }else{
                imageView.setVisibility(View.INVISIBLE);
            }
        }
    }
}
